package cn.caidabao.gb.component.sip.server.request.recieve;


import cn.caidabao.gb.bean.GBSipRegisterSession;
import cn.caidabao.gb.bean.GBSipContext;
import cn.caidabao.gb.component.sip.CustomSipServer;
import cn.caidabao.gb.util.MD5Utils;
import gov.nist.javax.sip.address.SipUri;
import gov.nist.javax.sip.header.WWWAuthenticate;
import gov.nist.javax.sip.message.SIPRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import javax.sip.*;
import javax.sip.address.Address;
import javax.sip.header.AuthorizationHeader;
import javax.sip.header.ExpiresHeader;
import javax.sip.message.Response;
import java.util.UUID;

import static cn.caidabao.gb.component.sip.server.storage.SessionStorage.gbSessionStorage;


@Slf4j
public class DefaultRegisterHandler implements RequestHandler<Void> {
    @Override
    @SneakyThrows
    public Void handleRequest(RequestEvent event, GBSipContext context){
        SIPRequest request = (SIPRequest) event.getRequest();
        Address address = request.getFromHeader().getAddress();
        SipUri uri = (SipUri) address.getURI();
        String user = uri.getUser();
        AuthorizationHeader authorization = (AuthorizationHeader)request.getHeader(AuthorizationHeader.NAME);
        ExpiresHeader expiresHeader = (ExpiresHeader)request.getHeader(ExpiresHeader.NAME);
        boolean isUnRegister = expiresHeader!=null&&expiresHeader.getExpires()==0;
        SipProvider sipProvider = context.getSipProvider();
        if (authorization==null){
            log.info(user+":"+(isUnRegister?"注销":"注册")+"未认证");
            Response response = CustomSipServer.messageFactory.createResponse(401, request);
            WWWAuthenticate wwwAuthenticate = new WWWAuthenticate();
            wwwAuthenticate.setAlgorithm("MD5");
            wwwAuthenticate.setNonce(UUID.randomUUID().toString().replace("-",""));
            wwwAuthenticate.setOpaque("OnlyGBSip");
            wwwAuthenticate.setRealm("OnlyGBSIP-Server");
            response.addHeader(wwwAuthenticate);
            ServerTransaction serverTransaction = event.getServerTransaction();
            if (serverTransaction==null){
                serverTransaction = sipProvider.getNewServerTransaction(request);
            }
            serverTransaction.sendResponse(response);
        }else {
            String response = authorization.getResponse();
            // Calculate HA1
            String ha1 = MD5Utils.md5(user + ":" + authorization.getRealm()+ ":" + "123456");

            // Calculate HA2
            String ha2 = MD5Utils.md5("REGISTER" + ":" + authorization.getURI().toString());

            // Calculate Response
            String ha3 = MD5Utils.md5(ha1 + ":" + authorization.getNonce() + ":" + ha2);

            if (ha3.equals(response)){
                ServerTransaction serverTransaction = event.getServerTransaction();
                if (serverTransaction==null){
                    serverTransaction = sipProvider.getNewServerTransaction(request);
                }
                log.info(user+":"+(isUnRegister?"注销":"注册")+"成功");
                serverTransaction.sendResponse(CustomSipServer.messageFactory.createResponse(200,request));
                if (isUnRegister){
                    gbSessionStorage.remove(user);
                }else {
                    GBSipRegisterSession gbSipRegisterSession = new GBSipRegisterSession();
                    gbSipRegisterSession.setIp(request.getRemoteAddress().getHostAddress());
                    gbSipRegisterSession.setPort(String.valueOf(request.getRemotePort()));
                    gbSipRegisterSession.setSipProvider(sipProvider);
                    gbSipRegisterSession.setUsername(user);
                    gbSipRegisterSession.setPassword("123456");
                    gbSipRegisterSession.setDeviceId(user);
                    gbSessionStorage.put(user, gbSipRegisterSession);
                }
            }
        }

        return null;
    }
}
